package umls.data;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import jdbc.UMLS_DB_Interface;

public class ConceptCandidate {
	private String CUI;
	private String ConceptCandidatePreferredTerm;
	private TreeMap<String, ExpandedConcept> ExpandedConceptMap;

	public ConceptCandidate() {
		this.CUI = "";
		this.ConceptCandidatePreferredTerm = "";
		this.ExpandedConceptMap = new TreeMap<String, ExpandedConcept>();
	}

	public ConceptCandidate(String CUI, String ConceptCandidatePreferredTerm) {
		this.CUI = CUI;
		this.ConceptCandidatePreferredTerm = ConceptCandidatePreferredTerm;
		this.ExpandedConceptMap = new TreeMap<String, ExpandedConcept>();
	}

	public void SetCUI(String CUI) {
		this.CUI = CUI;
	}

	public void SetConceptCandidatePreferredTerm(
			String ConceptCandidatePreferredTerm) {
		this.ConceptCandidatePreferredTerm = ConceptCandidatePreferredTerm;
	}

	public String GetCUI() {
		return this.CUI;
	}

	public String GetConceptCandidatePreferredTerm() {
		return this.ConceptCandidatePreferredTerm;
	}

	public void CreateExpandedConcepts(UMLS_DB_Interface umlsdb)
			throws SQLException {
		ArrayList<String> cuisandrelations = umlsdb
				.GetCUIandRelationsByCUI(CUI);

		Iterator<String> cuisandrelations_it = cuisandrelations.iterator();

		while (cuisandrelations_it.hasNext()) {
			String cuiandrelation = cuisandrelations_it.next();

			String[] s = cuiandrelation.split(":");

			String cui = s[0];
			String rel = s[1];
			String rela = s[2];

			ExpandedConcept expandedconcept;

			if ((expandedconcept = ExpandedConceptMap.get(cui)) == null) {
				expandedconcept = new ExpandedConcept();
				expandedconcept.SetECui(cui);

				ArrayList<String> preferredStrings = umlsdb
						.GetPreferedNameByCUI(cui);
				Iterator<String> preferredStrings_it = preferredStrings
						.iterator();
				while (preferredStrings_it.hasNext()) {
					expandedconcept
							.AddPreferredTerm(preferredStrings_it.next());
				}

				expandedconcept.SetSourceCUI(this.GetCUI());
				expandedconcept.SetSourceCUITerm(this
						.GetConceptCandidatePreferredTerm());
				expandedconcept.AddRelation(rel, rela);

				ExpandedConceptMap.put(cui, expandedconcept);
			} else {
				expandedconcept.AddRelation(rel, rela);

				ExpandedConceptMap.put(cui, expandedconcept);
			}

		}
	}

	// this method create the expanded concepts but it also returns the Semantic
	// Type
	// for each cui create an expanded concept if it does not exist, otherwise
	// it adds
	// all the regarding attributes.
	public void CreateExpandedConceptsBySemanticType(UMLS_DB_Interface umlsdb)
			throws SQLException {
		// ArrayList<String> cuisandrelations =
		// umlsdb.GetCUIandRelationsByCUI(CUI);

		ArrayList<String> cuisandrelations = umlsdb
				.GetCUIRelationsAndSemTypeByCUI(CUI);

		Iterator<String> cuisandrelations_it = cuisandrelations.iterator();

		while (cuisandrelations_it.hasNext()) {
			String cuiandrelation = cuisandrelations_it.next();

			String[] s = cuiandrelation.split(":");

			String cui = s[0];
			String rel = s[1];
			String rela = s[2];
			String tui = s[3];
			String sty = s[4];

			ExpandedConcept expandedconcept;

			if ((expandedconcept = ExpandedConceptMap.get(cui)) == null) {
				expandedconcept = new ExpandedConcept();
				expandedconcept.SetECui(cui);

				ArrayList<String> preferredStrings = umlsdb
						.GetPreferedNameByCUI(cui);
				Iterator<String> preferredStrings_it = preferredStrings
						.iterator();
				while (preferredStrings_it.hasNext()) {
					expandedconcept
							.AddPreferredTerm(preferredStrings_it.next());
				}

				expandedconcept.SetSourceCUI(this.GetCUI());
				expandedconcept.SetSourceCUITerm(this
						.GetConceptCandidatePreferredTerm());
				expandedconcept.AddRelation(rel, rela);
				expandedconcept.AddSemanticType(tui, sty);

				ExpandedConceptMap.put(cui, expandedconcept);
			} else {
				expandedconcept.AddRelation(rel, rela);
				expandedconcept.AddSemanticType(tui, sty);

				ExpandedConceptMap.put(cui, expandedconcept);
			}

		}
	}

	public ArrayList<String> GetAllPreferredTermsList() {
		ArrayList<String> result = new ArrayList<String>();

		Set econcept_set = this.ExpandedConceptMap.entrySet();

		Iterator econcept_it = econcept_set.iterator();

		// iteration through extended concepts
		while (econcept_it.hasNext()) {
			Map.Entry<String, ExpandedConcept> entry = (Map.Entry<String, ExpandedConcept>) econcept_it
					.next();

			ExpandedConcept econcept = (ExpandedConcept) entry.getValue();

			ArrayList<String> temp = econcept
					.GetECUIPreferredTermsAsArrayList();

			Iterator<String> it = temp.iterator();

			// for each extended concept iterate through the terms and save it
			// in results
			while (it.hasNext()) {
				result.add(it.next());
			}
		}

		return result;
	}

	public ArrayList<String> GetAllPreferredTermsListFilteredBySemType(
			SemGroupConfReader semgroupconfreader) {
		ArrayList<String> result = new ArrayList<String>();

		Set econcept_set = this.ExpandedConceptMap.entrySet();

		Iterator econcept_it = econcept_set.iterator();

		// iteration through extended concepts
		while (econcept_it.hasNext()) {
			Map.Entry<String, ExpandedConcept> entry = (Map.Entry<String, ExpandedConcept>) econcept_it
					.next();

			ExpandedConcept econcept = (ExpandedConcept) entry.getValue();

			ArrayList<String> econceptTUIs = econcept.GetTUIArrayList();

			Iterator<String> econceptTUIs_it = econceptTUIs.iterator();

			while (econceptTUIs_it.hasNext()) {
				String econcepttui = econceptTUIs_it.next();
				if (semgroupconfreader.isAllowedSemanticType(econcepttui)) {
					ArrayList<String> temp = econcept
							.GetECUIPreferredTermsAsArrayList();

					Iterator<String> it = temp.iterator();

					// for each extended concept iterate through the terms and
					// save it in results
					while (it.hasNext()) {
						result.add(it.next());
					}
				}
			}
		}

		return result;
	}

	@Override
	public String toString() {
		StringBuilder result = new StringBuilder();
		String NEW_LINE = System.getProperty("line.separator");

		result.append("CUI: " + this.CUI + NEW_LINE);

		result.append("ConceptCandidatePreferredTerm: "
				+ this.ConceptCandidatePreferredTerm + NEW_LINE);

		Set econcept_set = this.ExpandedConceptMap.entrySet();

		Iterator econcept_it = econcept_set.iterator();

		while (econcept_it.hasNext()) {
			Map.Entry<String, ExpandedConcept> entry = (Map.Entry<String, ExpandedConcept>) econcept_it
					.next();
			// ExpandedConcept econcept = (ExpandedConcept) econcept_it.next();

			ExpandedConcept econcept = (ExpandedConcept) entry.getValue();

			result.append("\tExpanded Concept: " + econcept.GetECUI()
					+ NEW_LINE);
			result.append("\tPreferred Strings: " + NEW_LINE
					+ econcept.PrintPreferredTermsAsString());
			result.append("\tRelations: " + NEW_LINE
					+ econcept.PrintRelationsAsString());
			result.append("\tSemantic Types: " + NEW_LINE
					+ econcept.PrintSemanticTypesAsString() + NEW_LINE);
		}

		return result.toString();
	}

}
